#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/ipc.h>
#include <errno.h>
#include <sys/shm.h>
#include <sys/msg.h>
#include <string.h>
#include "cJSON.h"

pthread_t tidA, tidB;
char buffer_data[1024] = {0};
int shmid, msgid;
int ret;
void *preath_processR(void *arg)
{
    // 获取客户端连接套接字作为参数
    int acceptfd = *(int *)arg;
    // 共享内存设置
    key_t key1 = ftok("./test1.txt", 'a');
    if (key1 < 0)
    {
        perror("ftok key1 err");
        pthread_exit(NULL);
    }

    // 创建或获取共享内存
    shmid = shmget(key1, 1024, IPC_CREAT | 0666);
    if (shmid < 0)
    {
        perror("shmget err");
        pthread_exit(NULL);
    }

    // 附加共享内存到当前进程
    char *shmaddr = (char *)shmat(shmid, NULL, 0);
    if (shmaddr == (char *)-1)
    {
        perror("shmat err");
        pthread_exit(NULL);
    }

    printf("Shared memory attached at address %p\n", shmaddr);

    while (1)
    {
        // 从客户端接收数据
        memset(buffer_data, 0, sizeof(buffer_data));
        ret = recv(acceptfd, buffer_data, sizeof(buffer_data) - 1, 0);

        if (ret <= 0)
        {
            if (ret == 0)
            {
                printf("Client disconnected\n");
            }
            else
            {
                perror("recv error");
            }
            break;
        }

        printf("Received from client: %s\n", buffer_data);

        // 1. 解析 JSON
        cJSON *root = cJSON_Parse(buffer_data);
        if (!root)
        {
            printf("JSON 解析失败！\n");
            return NULL;
        }

        // 2. 获取 data 数组
        cJSON *data_array = cJSON_GetObjectItem(root, "data");

        // 3. 遍历数组
        int array_size = cJSON_GetArraySize(data_array);
        for (int i = 0; i < array_size; i++)
        {
            cJSON *tmp = cJSON_GetArrayItem(data_array, i);

            cJSON *item = cJSON_GetObjectItem(tmp, "key");
            printf("%s=%d\n", item->string, item->valueint);

            // item = cJSON_GetObjectItem(tmp, "val");
            // printf("%s=%d\n",item->string,item->valueint);
            cJSON *val_item = cJSON_GetObjectItem(tmp, "val");
            if (val_item)
            {
                printf("%s=", val_item->string);
               
                    // 判断是整数还是浮点数
                    if (val_item->valuedouble == (int)val_item->valuedouble)
                    {
                        printf("%d\n", (int)val_item->valuedouble); // 整数
                    }
                    else
                    {
                        printf("%.2f\n", val_item->valuedouble); // 浮点数
                    }
                
            }

            printf("\n");
        }
        // 将处理后的数据写入共享内存
        strncpy(shmaddr, buffer_data, 1024 - 1);
        // 确保字符串终止
        shmaddr[1024 - 1] = '\0';
        // 释放JSON内存
        cJSON_Delete(root);
        root = NULL;
    }

    // 分离共享内存
    shmdt(shmaddr);

    // 关闭客户端连接
    close(acceptfd);

    pthread_exit(NULL);
}
void *preath_processW(void *arg)
{
    int acceptfd = *(int *)arg;
    // 消息队列设置
    key_t key2 = ftok("./test2.txt", 'b');
    if (key2 < 0)
    {
        perror("ftok key2 错误");
        pthread_exit(NULL);
    }

    // 创建或获取消息队列
    msgid = msgget(key2, IPC_CREAT | 0666);
    if (msgid < 0)
    {
        perror("msgget 错误");
        pthread_exit(NULL);
    }

    // 附加到共享内存（使用与preath_processR相同的shmid）
    char *shmaddr = (char *)shmat(shmid, NULL, 0);
    if (shmaddr == (char *)-1)
    {
        perror("写入线程 shmat 错误");
        pthread_exit(NULL);
    }

    // printf("写入线程已附加到共享内存地址 %p\n", shmaddr);

    while (1)
    {
        // 检查共享内存是否有数据
        // if (strlen(shmaddr) > 0)
        // {
        const char *fan_msg = "FAN_ON";
        if (send(acceptfd, fan_msg, strlen(fan_msg), 0) < 0)
        {
            perror("send FAN_ON failed");
            break;
        }
        else
        {
            printf("已经发送FAN_ON");
        }

        memset(shmaddr, 0, 1024); // 清空共享内存
        // }

        usleep(500000); // 休眠500ms避免CPU占用过高
    }

    // 分离共享内存
    shmdt(shmaddr);

    pthread_exit(NULL);
}
int main(int argc, char const *argv[])
{

    // 1.创建套接字
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0)
    {
        perror("socket err");
        return -1;
    }
    // 2.填充结构体
    struct sockaddr_in saddr, caddr;
    saddr.sin_family = AF_INET;
    saddr.sin_port = htons(8885);
    saddr.sin_addr.s_addr = inet_addr("192.168.0.139");

    socklen_t len = sizeof(caddr);

    // 3.绑定信息
    int ret = bind(sockfd, (struct sockaddr *)&saddr, len);
    if (ret < 0)
    {
        perror("bind err");
        return -1;
    }
    // 4.监听
    if (listen(sockfd, 5) < 0)
    {
        perror("listen err");
        return -1;
    }

    // 循环服务器
    while (1)
    {

        // 5.等待连接
        int acceptfd = accept(sockfd, (struct sockaddr *)&caddr, &len);
        if (acceptfd < 0)
        {
            perror("accept err");
            return -1;
        }
        printf("accept ok\n");
        // 打印来自客户端的ip地址和端口号
        printf("client ip : %s  port:%d\n", inet_ntoa(caddr.sin_addr), ntohs(caddr.sin_port));
        // 创建线程
        pthread_create(&tidA, NULL, preath_processR, &acceptfd);
        // pthread_create(&tidB, NULL, preath_processW, &acceptfd);
        while (1)
        {
        }
        // 8.关闭
        pthread_detach(tidA);
        close(acceptfd);
    }
    close(sockfd);

    return 0;
}
